package com.shanzmoo.admin.manager.store;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.shanzmoo.base.bean.PageRespBase;
import com.shanzmoo.base.constant.StoreStockIoType;
import com.shanzmoo.core.cache.CurrentUserCache;
import com.shanzmoo.core.manager.store.StoreStockManager;
import com.shanzmoo.db.store.entity.StoreStockCheckBillDetailEntity;
import com.shanzmoo.db.store.entity.StoreStockCheckBillEntity;
import com.shanzmoo.db.store.entity.StoreStockIoEntity;
import com.shanzmoo.db.store.entity.query.StoreStockCheckBillQuery;
import com.shanzmoo.db.store.entity.vo.StoreStockCheckBillDetailVO;
import com.shanzmoo.db.store.entity.vo.StoreStockCheckBillVO;
import com.shanzmoo.db.store.service.IStoreStockCheckBillDetailService;
import com.shanzmoo.db.store.service.IStoreStockCheckBillService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;


/**
 * 库存盘点单 管理器
 *
 * @author fs 2021-03-09
 */
@Slf4j
@Component
public class StoreStockCheckBillManager {

    @Autowired
    private IStoreStockCheckBillService storeStockCheckBillService;
    @Autowired
    private IStoreStockCheckBillDetailService storeStockCheckBillDetailService;
    @Autowired
    private StoreStockManager storeStockManager;

    /**
     * 分页查询
     */
    public PageRespBase<StoreStockCheckBillVO> queryPage(StoreStockCheckBillQuery query) {
        Page page = PageHelper.startPage(query.getPageNum(), query.getPageSize());
        List<StoreStockCheckBillVO> reList = storeStockCheckBillService.queryPageList(query);
        for(StoreStockCheckBillVO one:reList){
            List<StoreStockCheckBillDetailEntity> details = storeStockCheckBillDetailService.list(Wrappers.<StoreStockCheckBillDetailEntity>lambdaQuery().eq(StoreStockCheckBillDetailEntity::getBillId,one.getId()));
            List<StoreStockCheckBillDetailVO> detailVos = new ArrayList<>();
            for(StoreStockCheckBillDetailEntity detail:details){
                detailVos.add(BeanUtil.copyProperties(detail,StoreStockCheckBillDetailVO.class));
            }
            one.setDetails(detailVos);
        }
        PageRespBase<StoreStockCheckBillVO> result = PageRespBase.create(page, reList);
        return result;
    }

    public void cancel(StoreStockCheckBillEntity tmp) {
        StoreStockCheckBillEntity db = storeStockCheckBillService.getById(tmp.getId());
        Assert.isTrue(db.getStatus()==0,"只有未审核才能作废");
        db.setStatus(9);
        db.setUpdateTime(LocalDateTime.now());
        db.setCancelReason(tmp.getCancelReason());
        boolean update = storeStockCheckBillService.updateById(db);
        Assert.isTrue(update,"导入单状态更新失败");
    }

    public StoreStockCheckBillVO info(Integer id) {
        StoreStockCheckBillVO vo =  storeStockCheckBillService.findById(id);
        List<StoreStockCheckBillDetailEntity> childs = storeStockCheckBillDetailService.lambdaQuery().eq(StoreStockCheckBillDetailEntity::getBillId,id).list();
        List<StoreStockCheckBillDetailVO> list = new ArrayList<>();
        for(StoreStockCheckBillDetailEntity child:childs){
            list.add(BeanUtil.copyProperties(child,StoreStockCheckBillDetailVO.class));
        }
        vo.setDetails(list);
        return vo;
    }

    public void exmine(StoreStockCheckBillEntity entity) {
        StoreStockCheckBillEntity data = storeStockCheckBillService.getById(entity.getId());
        Assert.isTrue(data!=null&&data.getStatus()==0,"只有未审核才能审核");
        data.setStatus(1);
        data.setRemark(entity.getRemark());
        data.setExamineUser(CurrentUserCache.getUserId());
        data.setExamineTime(LocalDateTime.now());
        data.setUpdateTime(LocalDateTime.now());
        boolean update = storeStockCheckBillService.updateById(data);
        Assert.isTrue(update,"盘点单状态更新失败");
    }

    @Transactional(rollbackFor = Exception.class)
    public void enter(StoreStockCheckBillEntity entity, List<StoreStockCheckBillDetailEntity> details) {
        Assert.notEmpty(details,"盘点明细不可为空");
        StoreStockCheckBillEntity data = storeStockCheckBillService.getById(entity.getId());
        Assert.isTrue(data!=null&&data.getStatus()==1,"只有已审核才能录入");
        data.setStatus(2);
        data.setUpdateTime(LocalDateTime.now());
        boolean update = storeStockCheckBillService.updateById(data);
        Assert.isTrue(update,"盘点单状态更新失败");
        for(StoreStockCheckBillDetailEntity detail:details){
            detail.setBillId(data.getId());
            detail.setUpdateTime(LocalDateTime.now());
            update = storeStockCheckBillDetailService.saveOrUpdate(detail);
            Assert.isTrue(update,"盘点单明细保存失败");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void complete(Integer billId, String remark) {
        StoreStockCheckBillEntity data = storeStockCheckBillService.getById(billId);
        Assert.isTrue(data!=null&&data.getStatus()==2,"只有已录入才能完成盘点");

        data.setStatus(3);
        data.setCheckRemark(remark);
        data.setCheckTime(LocalDateTime.now());
        data.setCheckUser(CurrentUserCache.getUserId());
        boolean update = storeStockCheckBillService.updateById(data);
        Assert.isTrue(update,"盘点单状态更新失败");

        List<StoreStockCheckBillDetailEntity> details = storeStockCheckBillDetailService.lambdaQuery()
                .eq(StoreStockCheckBillDetailEntity::getBillId, billId)
                .list();
        Assert.notEmpty(details,"盘点明细不可为空");

        // 库存流水
        List<StoreStockIoEntity> stockIoList = new ArrayList<>();
        for(StoreStockCheckBillDetailEntity detail:details){
            // 差异
            int diff = detail.getActualSkuNum() - detail.getSysSkuNum();
            if (diff != 0) {
                StoreStockIoEntity ssi = new StoreStockIoEntity();
                ssi.setSku(detail.getSku());
                ssi.setType(diff>0 ? StoreStockIoType.CHECK_PROFIT : StoreStockIoType.CHECK_LOSS);
                ssi.setStoreCode(detail.getStoreCode());
                ssi.setFlow(true);
                ssi.setSkuNum(diff);
                ssi.setRemark(detail.getDifferentRemark());
                ssi.setOriginBill(data.getBillNo());
                ssi.setOriginBillType(4);
                ssi.setCreateUser(CurrentUserCache.getUserId());

                stockIoList.add(ssi);
            }
        }
        // 更新实时库存
        storeStockManager.updateByIoList(stockIoList, CurrentUserCache.getUserId());
    }
}
